#include "scripting/script_translator.h"
#include "scripting/script_task_object_pool.h"
#include "scheduler/sequence_scheduler.h"
#include "scheduler/fallback_scheduler.h"
#include "scheduler/inverter_scheduler.h"
#include "scheduler/scheduler_factory.h"
#include "scheduler/if_then_else_scheduler.h"
#include "scheduler/repeat_scheduler.h"
#include "scheduler/retry_scheduler.h"
#include "scheduler/while_do_scheduler.h"
#include "scheduler/reactive_sequence_scheduler.h"
#include "scheduler/parallel_scheduler.h"
#include "scheduler/force_success_scheduler.h"
#include "scheduler/force_failure_scheduler.h"
#include "scripting/scheduler_generator.h"
#include "utils/utils/string_cast.h"

using namespace scheduler;
using namespace base::utils;

namespace script
{
class ScriptTranslatorData
{
private:
    friend class ScriptTranslator;
    std::string error_message;
    Token error_token;
    std::shared_ptr<ScriptTaskObjectPool> task_pool;
    std::shared_ptr<SchedulerGenerator> scheduler_generator;

private:
    /**
     * @brief:  设置错误描述，如果错误描述不为空，则不设置
     * @author: sherlock_lht
     */
    void setErrorInfo(const std::string &error_msg, const Token &token);

    /**
     * @brief:  解析根节点
     * @author: sherlock_lht
     */
    SchedulerOptional translateRootNode(const ASTNode &ast_node);

    /**
     * @brief:  翻译根语法树
     * @author: sherlock_lht
     */
    SchedulerOptional translateASTNode(const ASTNode &ast_node);
    SchedulerOptional translateOneStatement(const ASTNode &ast_node);

    /**
     * @brief:  翻译var声明
     * @author: sherlock_lht
     */
    bool translateVarDeclaration(const ASTNode &ast_node);

    /**
     * @brief:  翻译function声明
     * @author: sherlock_lht
     */
    bool translateFunctionDeclaration(const ASTNode &ast_node);
    SchedulerOptional translateFunctionExecuteStatement(const ASTNode &ast_node);

    SchedulerOptional translateExpressionStatement(const ASTNode &ast_node);

    SchedulerOptional translateAndStatement(const ASTNode &ast_node);
    SchedulerOptional translateOrStatement(const ASTNode &ast_node);
    SchedulerOptional translateNotStatement(const ASTNode &ast_node);

    std::optional<task::AbstractTaskConstPtr> translateIdentifierStatement(const ASTNode &ast_node);
    std::optional<scheduler::AbstractSchedulerConstPtr> translateIdentifierFuncStatement(const ASTNode &ast_node);

    /**
     * @brief:  翻译if语句
     * @author: sherlock_lht
     */
    SchedulerOptional translateIfStatement(const ASTNode &ast_node);
    bool translateIfConditionStatement(const ASTNode &ast_node, std::shared_ptr<IfThenElseScheduler> &if_scheduler);
    bool translateIfThenStatement(const ASTNode &ast_node, std::shared_ptr<IfThenElseScheduler> &if_scheduler);
    bool translateIfElseStatement(const ASTNode &ast_node, std::shared_ptr<IfThenElseScheduler> &if_scheduler);

    /**
     * @brief:  翻译repeat语句
     * @author: sherlock_lht
     */
    SchedulerOptional translateRepeatStatement(const ASTNode &ast_node);

    /**
     * @brief:  翻译retry语句
     * @author: sherlock_lht
     */
    SchedulerOptional translateRetryStatement(const ASTNode &ast_node);

    /**
     * @brief:  翻译while循环
     * @author: sherlock_lht
     */
    SchedulerOptional translateWhileLoop(const ASTNode &ast_node);
    bool translateWhileConditionStatement(const ASTNode &ast_node, std::shared_ptr<WhileDoScheduler> &while_scheduler);
    bool translateWhileExecuteStatement(const ASTNode &ast_node, std::shared_ptr<WhileDoScheduler> &while_scheduler);

    /**
     * @brief:  翻译响应式语句
     * @author: sherlock_lht
     */
    SchedulerOptional translateReactiveStatement(const ASTNode &ast_node);
    bool translateReactiveConditionStatement(const ASTNode &ast_node, std::shared_ptr<ReactiveSequenceScheduler> &reactive_sequence_scheduler);
    bool translateReactiveExecuteStatement(const ASTNode &ast_node, std::shared_ptr<ReactiveSequenceScheduler> &reactive_sequence_scheduler);

    /**
     * @brief:  翻译parallel语句
     * @author: sherlock_lht
     */
    SchedulerOptional translateParallelStatement(const ASTNode &ast_node);
    bool translateParallelExecuteStatement(const ASTNode &node, std::shared_ptr<ParallelScheduler> &parallel_scheduler);

    SchedulerOptional translateForcePassStatement(const ASTNode &ast_node);
    bool translateForcePassExecuteStatement(const ASTNode &node, std::shared_ptr<ForceSuccessScheduler> &force_success_scheduler);

    SchedulerOptional translateForceFailStatement(const ASTNode &ast_node);
    bool translateForceFailExecuteStatement(const ASTNode &node, std::shared_ptr<ForceFailureScheduler> &force_failure_scheduler);
};
void ScriptTranslatorData::setErrorInfo(const std::string &error_msg, const Token &token)
{
    if (error_message.empty())
    {
        error_message = "translate fail, " + error_msg;
        error_token = token;
    }
}
SchedulerOptional ScriptTranslatorData::translateASTNode(const ASTNode &ast_node)
{
    auto sequence_scheduler = SchedulerFactory<SequenceScheduler>::createScheduler("sequence_scheduler");
    if (ASTNodeType::Identifier == ast_node.type)
    {
        if (auto task_object = translateIdentifierStatement(ast_node))
        {
            sequence_scheduler->appendTask(task_object.value());
        }
        else if (auto function_object = translateIdentifierFuncStatement(ast_node))
        {
            sequence_scheduler->appendScheduler(function_object.value());
        }
        else
        {
            setErrorInfo("variable " + ast_node.value + " is not be defined", ast_node.token);
            return std::nullopt;
        }
    }
    else if (ASTNodeType::VarDeclaration == ast_node.type)
    {
        if (!translateVarDeclaration(ast_node))
        {
            return std::nullopt;
        }
    }
    else if (ASTNodeType::Root == ast_node.type)
    {
        return translateRootNode(ast_node);
    }
    else
    {
        if (auto scheduler = translateOneStatement(ast_node))
        {
            sequence_scheduler->appendScheduler(scheduler.value());
        }
        else
        {
            setErrorInfo("translate ast node fail, unknown ast node type", ast_node.token);
            return std::nullopt;
        }
    }
    return sequence_scheduler;
}
SchedulerOptional ScriptTranslatorData::translateOneStatement(const ASTNode &ast_node)
{
    switch (ast_node.type)
    {
        case ASTNodeType::IfStatement:
            return translateIfStatement(ast_node);
        case ASTNodeType::RepeatStatement:
            return translateRepeatStatement(ast_node);
        case ASTNodeType::RetryStatement:
            return translateRetryStatement(ast_node);
        case ASTNodeType::WhileLoop:
            return translateWhileLoop(ast_node);
        case ASTNodeType::ReactiveStatement:
            return translateReactiveStatement(ast_node);
        case ASTNodeType::ParallelStatement:
            return translateParallelStatement(ast_node);
        case ASTNodeType::ForcePassStatement:
            return translateForcePassStatement(ast_node);
        case ASTNodeType::ForceFailStatement:
            return translateForceFailStatement(ast_node);
        case ASTNodeType::AND:
            return translateAndStatement(ast_node);
        case ASTNodeType::NOT:
            return translateNotStatement(ast_node);
        case ASTNodeType::Root:
            return translateRootNode(ast_node);
        default:
            setErrorInfo("invalid ast type: " + std::string(astNodeTypeToString(ast_node.type)), ast_node.token);
            return std::nullopt;
    }
}
SchedulerOptional ScriptTranslatorData::translateRootNode(const ASTNode &ast_node)
{
    auto root_sequence = SchedulerFactory<SequenceScheduler>::createScheduler("root_sequence");
    for (const auto &node: ast_node.children)
    {
        if (ASTNodeType::VarDeclaration == node.type)//特殊处理
        {
            if (!translateVarDeclaration(node))
            {
                return std::nullopt;
            }
        }
        else if (ASTNodeType::FuncDeclaration == node.type)//特殊处理
        {
            if (!translateFunctionDeclaration(node))
            {
                return std::nullopt;
            }
        }
        else if (auto scheduler = translateASTNode(node))
        {
            root_sequence->appendScheduler(scheduler.value());
        }
        else
        {
            return std::nullopt;
        }
    }
    return root_sequence;
}
bool ScriptTranslatorData::translateVarDeclaration(const ASTNode &ast_node)
{
    std::string task_variable = ast_node.value;
    if (ast_node.children.size() != 2)//一个是变量类型，一个是对象传参
    {
        setErrorInfo("expected task name after " + task_variable, ast_node.token);
        return false;
    }
    std::string task_type = ast_node.children.at(0).value;
    std::string task_name = ast_node.children.at(1).value;

    if (!task_pool->createObject(task_variable, task_type, task_name))
    {
        setErrorInfo("create task object fail, " + task_pool->getLastErrorMessage(), ast_node.token);
        return false;
    }
    return true;
}
bool ScriptTranslatorData::translateFunctionDeclaration(const ASTNode &ast_node)
{
    std::string function_name = ast_node.value;
    if (ast_node.children.size() != 1)
    {
        setErrorInfo("expected function name after " + function_name, ast_node.token);
        return false;
    }

    ASTNode func_exec_node = ast_node.children.at(0);
    auto scheduler = translateFunctionExecuteStatement(func_exec_node);
    if (!scheduler)
    {
        setErrorInfo("expected function execute statement", ast_node.token);
        return false;
    }
    if (!task_pool->createFunction(function_name, scheduler.value()))
    {
        setErrorInfo("create function object fail, " + task_pool->getLastErrorMessage(), ast_node.token);
        return false;
    }
    return true;
}
SchedulerOptional ScriptTranslatorData::translateFunctionExecuteStatement(const ASTNode &ast_node)
{
    return translateASTNode(ast_node);
}
SchedulerOptional ScriptTranslatorData::translateExpressionStatement(const ASTNode &ast_node)
{
    //表达式只有一个子节点，且只能出现and/not/or 3种类型
    if (ast_node.children.size() != 1)
    {
        setErrorInfo("expected expression content", ast_node.token);
        return std::nullopt;
    }
    ASTNode content_node = ast_node.children.at(0);
    switch (content_node.type)
    {
        case ASTNodeType::AND:
            return translateAndStatement(content_node);
        case ASTNodeType::OR:
            return translateOrStatement(content_node);
        case ASTNodeType::NOT:
            return translateNotStatement(content_node);
        default:
            setErrorInfo("expected expression content, unknown content node type", ast_node.token);
            return std::nullopt;
    }
}
SchedulerOptional ScriptTranslatorData::translateAndStatement(const ASTNode &ast_node)
{
    //and内只有identifier/not/expression
    auto and_sequence = SchedulerFactory<SequenceScheduler>::createScheduler("and_sequence");
    for (const auto &node: ast_node.children)
    {
        if (ASTNodeType::Identifier == node.type)
        {
            if (auto task = translateIdentifierStatement(node))
            {
                and_sequence->appendTask(task.value());
                continue;
            }
            if (auto func = translateIdentifierFuncStatement(node))
            {
                and_sequence->appendScheduler(func.value());
                continue;
            }
            return std::nullopt;
        }
        if (ASTNodeType::NOT == node.type)
        {
            if (auto scheduler = translateNotStatement(node))
            {
                and_sequence->appendScheduler(scheduler.value());
                continue;
            }
            return std::nullopt;
        }
        if (ASTNodeType::Expression == node.type)
        {
            if (auto scheduler = translateExpressionStatement(node))
            {
                and_sequence->appendScheduler(scheduler.value());
                continue;
            }
            return std::nullopt;
        }
        setErrorInfo("expected and statement, unknown ast type", node.token);
        return std::nullopt;
    }
    return and_sequence;
}
SchedulerOptional ScriptTranslatorData::translateOrStatement(const ASTNode &ast_node)
{
    //or内有identifier/not/and/expression
    auto or_sequence = SchedulerFactory<FallbackScheduler>::createScheduler("or_sequence");
    for (const auto &node: ast_node.children)
    {
        if (ASTNodeType::AND == node.type)
        {
            if (auto scheduler = translateAndStatement(node))
            {
                or_sequence->appendScheduler(scheduler.value());
                continue;
            }
            return std::nullopt;
        }
        if (ASTNodeType::Identifier == node.type)
        {
            if (auto task = translateIdentifierStatement(node))
            {
                or_sequence->appendTask(task.value());
                continue;
            }
            if (auto func = translateIdentifierFuncStatement(node))
            {
                or_sequence->appendScheduler(func.value());
                continue;
            }
            return std::nullopt;
        }
        if (ASTNodeType::NOT == node.type)
        {
            if (auto scheduler = translateNotStatement(node))
            {
                or_sequence->appendScheduler(scheduler.value());
                continue;
            }
            return std::nullopt;
        }
        if (ASTNodeType::Expression == node.type)
        {
            if (auto scheduler = translateExpressionStatement(node))
            {
                or_sequence->appendScheduler(scheduler.value());
                continue;
            }
            return std::nullopt;
        }
        setErrorInfo("expected and statement, unknown ast type", node.token);
        return std::nullopt;
    }
    return or_sequence;
}
SchedulerOptional ScriptTranslatorData::translateNotStatement(const ASTNode &ast_node)
{
    if (ast_node.children.size() != 1)
    {
        setErrorInfo("expected not statement, content error", ast_node.token);
        return std::nullopt;
    }
    auto not_scheduler = SchedulerFactory<InverterScheduler>::createScheduler("not_scheduler");
    ASTNode content_node = ast_node.children.at(0);
    //not后面是标识符
    if (ASTNodeType::Identifier == content_node.type)
    {
        if (auto task = translateIdentifierStatement(content_node))
        {
            not_scheduler->setTask(task.value());
            return not_scheduler;
        }
        if (auto func = translateIdentifierFuncStatement(content_node))
        {
            not_scheduler->setScheduler(func.value());
            return not_scheduler;
        }
        return std::nullopt;
    }
    //not后面是表达式
    if (ASTNodeType::Expression == content_node.type)
    {
        if (auto scheduler = translateExpressionStatement(content_node))
        {
            not_scheduler->setScheduler(scheduler.value());
            return not_scheduler;
        }
        return std::nullopt;
    }
    setErrorInfo("expected not statement, unknown ast type", content_node.token);
    return std::nullopt;
}
std::optional<task::AbstractTaskConstPtr> ScriptTranslatorData::translateIdentifierStatement(const ASTNode &ast_node)
{
    if (auto task_object = task_pool->getTaskObject(ast_node.value))
    {
        return task_object;
    }
    setErrorInfo(task_pool->getLastErrorMessage(), ast_node.token);
    return std::nullopt;
}
std::optional<scheduler::AbstractSchedulerConstPtr> ScriptTranslatorData::translateIdentifierFuncStatement(const ASTNode &ast_node)
{
    if (auto func_object = task_pool->getFunctionObject(ast_node.value))
    {
        return func_object;
    }
    setErrorInfo(task_pool->getLastErrorMessage(), ast_node.token);
    return std::nullopt;
}
SchedulerOptional ScriptTranslatorData::translateIfStatement(const ASTNode &ast_node)
{
    if (ast_node.children.size() != 2 && ast_node.children.size() != 3)
    {
        setErrorInfo("if statement must have expression and then executant, and maybe an executant", ast_node.token);
        return std::nullopt;
    }

    auto if_scheduler = SchedulerFactory<IfThenElseScheduler>::createScheduler("if_expression_scheduler");
    //条件
    if (!translateIfConditionStatement(ast_node.children.at(0), if_scheduler))
    {
        return std::nullopt;
    }
    //then执行体
    if (!translateIfThenStatement(ast_node.children.at(1), if_scheduler))
    {
        return std::nullopt;
    }
    //else执行体
    if (ast_node.children.size() == 3 && !translateIfElseStatement(ast_node.children.at(2), if_scheduler))
    {
        return std::nullopt;
    }
    return if_scheduler;
}
bool ScriptTranslatorData::translateIfConditionStatement(const ASTNode &ast_node, std::shared_ptr<IfThenElseScheduler> &if_scheduler)
{
    //if条件只有一个子节点，or/and/not/identifier
    if (ast_node.children.size() != 1)
    {
        setErrorInfo("generate if condition expression scheduler fail, content error", ast_node.token);
        return false;
    }
    bool res = false;
    ASTNode content_node = ast_node.children.at(0);
    switch (content_node.type)
    {
        case ASTNodeType::OR:
            if (auto scheduler = translateOrStatement(content_node))
            {
                res = true;
                if_scheduler->setConditionScheduler(scheduler.value());
            }
            break;
        case ASTNodeType::AND:
            if (auto scheduler = translateOneStatement(content_node))
            {
                res = true;
                if_scheduler->setConditionScheduler(scheduler.value());
            }
            break;
        case ASTNodeType::NOT:
            if (auto scheduler = translateNotStatement(content_node))
            {
                res = true;
                if_scheduler->setConditionScheduler(scheduler.value());
            }
            break;
        case ASTNodeType::Identifier:
            if (auto task = translateIdentifierStatement(content_node))
            {
                res = true;
                if_scheduler->setConditionTask(task.value());
            }
            if (auto func = translateIdentifierFuncStatement(content_node))
            {
                res = true;
                if_scheduler->setConditionScheduler(func.value());
            }
            break;
        default:
            setErrorInfo("generate if condition expression fail, unknown content type", content_node.token);
            break;
    }
    return res;
}
bool ScriptTranslatorData::translateIfThenStatement(const ASTNode &ast_node, std::shared_ptr<IfThenElseScheduler> &if_scheduler)
{
    if (auto then_scheduler = translateASTNode(ast_node))
    {
        if_scheduler->setThenScheduler(then_scheduler.value());
        return true;
    }
    return false;
}
bool ScriptTranslatorData::translateIfElseStatement(const ASTNode &ast_node, std::shared_ptr<IfThenElseScheduler> &if_scheduler)
{
    if (auto else_scheduler = translateASTNode(ast_node))
    {
        if_scheduler->setElseScheduler(else_scheduler.value());
        return true;
    }
    return false;
}
SchedulerOptional ScriptTranslatorData::translateRepeatStatement(const ASTNode &ast_node)
{
    bool is_ok = false;
    int32_t count = StringCast::toInt(ast_node.value, &is_ok);
    if (!is_ok)
    {
        setErrorInfo("expected repeat expression, repeat count to number fail", ast_node.token);
        return std::nullopt;
    }

    auto repeat_scheduler = SchedulerFactory<RepeatScheduler>::createScheduler("repeat_scheduler");
    repeat_scheduler->setRepeatCount(count);

    if (ast_node.children.empty())
    {
        //循环体可以是空的
        return repeat_scheduler;
    }
    //循环体不为空
    if (auto repeat_executant_scheduler = translateASTNode(ast_node.children.at(0)))
    {
        repeat_scheduler->setScheduler(repeat_executant_scheduler.value());
        return repeat_scheduler;
    }
    return std::nullopt;
}
SchedulerOptional ScriptTranslatorData::translateRetryStatement(const ASTNode &ast_node)
{
    bool is_ok = false;
    int32_t count = StringCast::toInt(ast_node.value, &is_ok);
    if (!is_ok)
    {
        setErrorInfo("expected retry expression, repeat count to number fail", ast_node.token);
        return std::nullopt;
    }

    auto retry_scheduler = SchedulerFactory<RetryScheduler>::createScheduler("retry_scheduler");
    retry_scheduler->setRetryCount(count);

    if (ast_node.children.empty())
    {
        //循环体可以是空的
        return retry_scheduler;
    }
    //循环体不为空
    if (auto repeat_executant_scheduler = translateASTNode(ast_node.children.at(0)))
    {
        retry_scheduler->setScheduler(repeat_executant_scheduler.value());
        return retry_scheduler;
    }
    return std::nullopt;
}
SchedulerOptional ScriptTranslatorData::translateWhileLoop(const ASTNode &ast_node)
{
    //if应该有1~2个子树，分别是判断表达式、执行语句
    if (ast_node.children.size() != 1 && ast_node.children.size() != 2)
    {
        setErrorInfo("while loop must have expression, and maybe loop executant", ast_node.token);
        return std::nullopt;
    }

    auto while_do_scheduler = SchedulerFactory<WhileDoScheduler>::createScheduler("while_do_scheduler");
    //条件
    if (!translateWhileConditionStatement(ast_node.children.at(0), while_do_scheduler))
    {
        return std::nullopt;
    }
    if (ast_node.children.size() == 2 && !translateWhileExecuteStatement(ast_node.children.at(1), while_do_scheduler))
    {
        return std::nullopt;
    }
    return while_do_scheduler;
}
bool ScriptTranslatorData::translateWhileConditionStatement(const ASTNode &ast_node, std::shared_ptr<WhileDoScheduler> &while_scheduler)
{
    //单task条件
    if (ast_node.children.size() == 1 && ast_node.children.at(0).type == ASTNodeType::Identifier)
    {
        auto condition_task = task_pool->getTaskObject(ast_node.children.at(0).value);
        if (condition_task)
        {
            while_scheduler->setWhileConditionTask(condition_task.value());
            return true;
        }
        setErrorInfo("‘" + ast_node.children.at(0).value + "’ " + "was not declared in this scope", ast_node.token);
        return false;
    }
    //多task条件
    auto expression_scheduler = scheduler_generator->generateExpressionScheduler(ast_node);
    if (expression_scheduler)
    {
        while_scheduler->setWhileConditionScheduler(expression_scheduler.value());
        return true;
    }
    setErrorInfo("generate while condition expression scheduler fail", ast_node.token);
    return false;
}
bool ScriptTranslatorData::translateWhileExecuteStatement(const ASTNode &ast_node, std::shared_ptr<WhileDoScheduler> &while_scheduler)
{
    if (auto else_scheduler = translateASTNode(ast_node))
    {
        while_scheduler->setExecuteScheduler(else_scheduler.value());
        return true;
    }
    return false;
}
SchedulerOptional ScriptTranslatorData::translateReactiveStatement(const ASTNode &ast_node)
{
    //if应该有1~2个子树，分别是响应语句、执行语句，执行语句可能为空
    if (ast_node.children.size() != 1 && ast_node.children.size() != 2)
    {
        setErrorInfo("reactive statement must have expression, and maybe an executant", ast_node.token);
        return std::nullopt;
    }

    auto reactive_sequence_scheduler = SchedulerFactory<ReactiveSequenceScheduler>::createScheduler("reactive_sequence_scheduler");

    if (!translateReactiveConditionStatement(ast_node.children.at(0), reactive_sequence_scheduler))
    {
        return std::nullopt;
    }
    if (ast_node.children.size() == 2 && !translateReactiveExecuteStatement(ast_node.children.at(1), reactive_sequence_scheduler))
    {
        return std::nullopt;
    }
    return reactive_sequence_scheduler;
}
bool ScriptTranslatorData::translateReactiveConditionStatement(const ASTNode &ast_node,
                                                               std::shared_ptr<ReactiveSequenceScheduler> &reactive_sequence_scheduler)
{
    //单task条件
    if (ast_node.children.size() == 1 && ast_node.children.at(0).type == ASTNodeType::Identifier)
    {
        auto condition_task = task_pool->getTaskObject(ast_node.children.at(0).value);
        if (condition_task)
        {
            reactive_sequence_scheduler->setReactiveTask(condition_task.value());
            return true;
        }
        setErrorInfo("‘" + ast_node.children.at(0).value + "’ " + "was not declared in this scope", ast_node.token);
        return false;
    }
    //多task条件
    auto expression_scheduler = scheduler_generator->generateExpressionScheduler(ast_node);
    if (expression_scheduler)
    {
        reactive_sequence_scheduler->appendExecuteScheduler(expression_scheduler.value());
        return true;
    }
    setErrorInfo("generate reactive condition expression scheduler fail", ast_node.token);
    return false;
}
bool ScriptTranslatorData::translateReactiveExecuteStatement(const ASTNode &ast_node,
                                                             std::shared_ptr<ReactiveSequenceScheduler> &reactive_sequence_scheduler)
{
    if (auto reactive_scheduler = translateASTNode(ast_node))
    {
        reactive_sequence_scheduler->appendExecuteScheduler(reactive_scheduler.value());
        return true;
    }
    return false;
}
SchedulerOptional ScriptTranslatorData::translateParallelStatement(const ASTNode &ast_node)
{
    //执行体可能为空
    auto parallel_scheduler = SchedulerFactory<ParallelScheduler>::createScheduler("parallel_scheduler");
    if (!translateParallelExecuteStatement(ast_node, parallel_scheduler))
    {
        return std::nullopt;
    }
    return parallel_scheduler;
}
bool ScriptTranslatorData::translateParallelExecuteStatement(const ASTNode &node, std::shared_ptr<ParallelScheduler> &parallel_scheduler)
{
    for (const auto &childNode: node.children)
    {
        auto scheduler = translateASTNode(childNode);
        if (!scheduler)
        {
            return false;
        }
        parallel_scheduler->appendScheduler(scheduler.value());
    }
    parallel_scheduler->setSuccessThreshold((int) node.children.size());
    return true;
}
SchedulerOptional ScriptTranslatorData::translateForcePassStatement(const ASTNode &ast_node)
{
    //force_pass只有一个执行体，且执行体可能为空
    auto force_pass_scheduler = SchedulerFactory<ForceSuccessScheduler>::createScheduler("force_success_scheduler");
    if (ast_node.children.size() == 1 && !translateForcePassExecuteStatement(ast_node.children.at(0), force_pass_scheduler))
    {
        return std::nullopt;
    }
    return force_pass_scheduler;
}
bool ScriptTranslatorData::translateForcePassExecuteStatement(const ASTNode &node, std::shared_ptr<ForceSuccessScheduler> &force_success_scheduler)
{
    if (auto scheduler = translateASTNode(node))
    {
        force_success_scheduler->setScheduler(scheduler.value());
        return true;
    }
    return false;
}
SchedulerOptional ScriptTranslatorData::translateForceFailStatement(const ASTNode &ast_node)
{
    //force_fail只有一个执行体，且执行体可能为空
    auto force_fail_scheduler = SchedulerFactory<ForceFailureScheduler>::createScheduler("force_failure_scheduler");
    if (ast_node.children.size() == 1 && !translateForceFailExecuteStatement(ast_node.children.at(0), force_fail_scheduler))
    {
        return std::nullopt;
    }
    return force_fail_scheduler;
}
bool ScriptTranslatorData::translateForceFailExecuteStatement(const ASTNode &node, std::shared_ptr<ForceFailureScheduler> &force_failure_scheduler)
{
    if (auto scheduler = translateASTNode(node))
    {
        force_failure_scheduler->setScheduler(scheduler.value());
        return true;
    }
    return false;
}
}

namespace script
{
ScriptTranslator::ScriptTranslator()
    : d(std::make_unique<ScriptTranslatorData>())
{
    d->task_pool = std::make_shared<ScriptTaskObjectPool>();
    d->scheduler_generator = std::make_shared<SchedulerGenerator>(d->task_pool->getTaskPoolPtr());
}
ScriptTranslator::~ScriptTranslator() = default;

SchedulerOptional ScriptTranslator::translate(const ASTNode &ast_node)
{
    if (ASTNodeType::Root != ast_node.type)
    {
        d->setErrorInfo("not a valid ast", ast_node.token);
        return std::nullopt;
    }
    return d->translateRootNode(ast_node);
}
void ScriptTranslator::getLastInfo(int *error_line, int *error_column, std::string *error_message) const
{
    *error_line = d->error_token.line;
    *error_column = d->error_token.column;
    *error_message = d->error_message;
}
}
